package org.smarthings.things.automation.rest.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;

import org.smarthings.things.automation.Rule;
import org.smarthings.things.automation.rest.resources.ActionResource;
import org.smarthings.things.automation.rest.resources.ConditionResource;
import org.smarthings.things.automation.rest.resources.RuleColleactionResource;
import org.smarthings.things.automation.rest.resources.RuleResource;
import org.smarthings.things.automation.rest.resources.TriggerResource;
import org.smarthings.things.commons.rest.VersionResource;
import org.smarthings.things.commons.utils.PaginationUtils;
import org.smarthings.things.commons.utils.QueryParametersUtils;

//TODO remove UriInfo parameter
public class RulesResourceFactory {

	public static final String RULES = "rules";
	public static final String RULE_UUID = "{ruleUUID}";

	public static final String VERSION = "version";

	public static VersionResource getVersion(UriInfo uri) {
		VersionResource version = new VersionResource();
		version.setHref(UriBuilder.fromPath(RULES).path(VERSION).build());
		version.setImplementationVersion("0.0.1");
		version.setImplementationVersion("0.0.1");
		return version;
	}

	public static RuleResource getRule(Rule rule, UriInfo uri) {
		RuleResource resource = new RuleResource();
		resource.setHref(UriBuilder.fromPath(RULES).path(RULE_UUID).build(rule.getUUID()));
		resource.setUUID(rule.getUUID());
		resource.setName(rule.getName());
		resource.setTags(rule.getTags());

		TriggerResource trigger = new TriggerResource();
		trigger.setExpression(rule.getTrigger().getExpression());
		resource.setTrigger(trigger);

		ActionResource action = new ActionResource();
		action.setLanguage(rule.getAction().getLanguage());
		action.setScript(rule.getAction().getScript());
		resource.setAction(action);

		if (rule.getCondition() != null) {
			ConditionResource condiition = new ConditionResource();
			condiition.setLanguage(rule.getCondition().getLanguage());
			condiition.setScript(rule.getCondition().getScript());
			resource.setCondition(condiition);
		}
		return resource;
	}

	public static RuleColleactionResource getRuleColleactionResource(List<Rule> rules, int offset,
			int limit, UriInfo uri) {
		RuleColleactionResource collection = new RuleColleactionResource();
		collection.setHref(UriBuilder.fromPath(RULES).build());
		collection.setOffset(offset);
		collection.setLimit(limit);
		int size = rules.size();
		collection.setFirst(UriBuilder.fromPath(RULES)
				.queryParam(QueryParametersUtils.LIMIT, limit)
				.queryParam(QueryParametersUtils.OFFSET, 0).build());
		collection.setLast(UriBuilder.fromPath(RULES)
				.queryParam(QueryParametersUtils.LIMIT, limit)
				.queryParam(QueryParametersUtils.OFFSET,
						size - PaginationUtils.calculateLastPageSize(offset, limit, size)).build());
		int next = PaginationUtils.calculateNextPageOffset(offset, limit, size);
		if (next < size) {
			collection.setNext(UriBuilder.fromPath(RULES)
					.queryParam(QueryParametersUtils.LIMIT, limit)
					.queryParam(QueryParametersUtils.OFFSET, next).build());
		}
		int previous = PaginationUtils.calculatePreviousPageOffset(offset, limit, size);
		if (previous > 0) {
			collection.setPrevious(UriBuilder.fromPath(RULES)
					.queryParam(QueryParametersUtils.LIMIT, limit)
					.queryParam(QueryParametersUtils.OFFSET, previous).build());
		}

		if (rules != null && rules.size() > 0) {
			List<RuleResource> items = new ArrayList<RuleResource>(rules.size());
			Iterator<Rule> rulesIterator = rules.iterator();
			while (rulesIterator.hasNext()) {
				RuleResource resource = getRule(rulesIterator.next(), uri);
				items.add(resource);
			}
			collection.setItems(items);
		}

		return collection;
	}

}
